package com.zyl.blog.common.response;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zyl.blog.common.enums.ResultCode;
import com.zyl.blog.common.enums.StatusCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog
 * @Package: com.zyl.common.response
 * @ClassName: Result
 * @Description: 通用响应结果封装类
 * @param <T> 响应数据的泛型类型
 * @Author FinalFantasy
 * @Date 2025/2/14-13:21
 */
@Data
@Accessors(chain = true)
@AllArgsConstructor
public class Result<T> implements DesensitizeWrapper<T> {

    /** 结果码（通常对应预定义的 {@link StatusCode} 或 {@link ResultCode} 枚举值） */
    private int code;

    /** 结果消息（成功/错误的描述信息） */
    private String msg;

    /** 响应数据（泛型类型，可为空） */
    private T data;

    @Override
    @JsonIgnore
    public T getWrappedData() {
        return this.data;
    }

    /*------------------ 核心静态工厂方法 ------------------*/

    /**
     * 构造一个成功响应（无数据）
     *
     * @return 成功响应实例（code=200, message="success"）
     */
    public static <T> Result<T> ok() {
        return of(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), getDefaultEmptyData());
    }

    /**
     * 构造一个成功响应（无数据,含有消息）
     *
     * @return 成功响应实例（code=200, message="${}", data=[]）
     */
    public static <T> Result<T> ok(String msg) {
        return of(ResultCode.SUCCESS.getCode(), msg, getDefaultEmptyData());
    }

    /**
     * 构造一个成功响应（携带数据）
     *
     * @param data 响应数据
     * @return 成功响应实例（code=200, message="success"）
     */
    public static <T> Result<T> ok(T data) {
        return of(ResultCode.SUCCESS.getCode(), "success", data);
    }

    /**
     * 构造一个默认错误响应（无数据）
     *
     * @return 错误响应实例（code=500, message="系统内部错误"）
     */
    public static <T> Result<T> fail() {
        return of(ResultCode.INTERNAL_ERROR.getCode(), ResultCode.INTERNAL_ERROR.getMessage(), getDefaultEmptyData());
    }

    /**
     * 构造一个自定义错误消息的响应
     *
     * @param message 错误描述
     * @return 错误响应实例（code=500, message=自定义消息）
     */
    public static <T> Result<T> fail(String message) {
        return of(ResultCode.INTERNAL_ERROR.getCode(), message, getDefaultEmptyData());
    }

    /*------------------ 新增：空数据默认值处理工具方法 ------------------*/

    /**
     * 获取默认空数据（根据类型自动适配）
     */
    @SuppressWarnings("unchecked") // 仅在确认安全时使用，集中管理警告
    private static <T> T getDefaultEmptyData() {
        /* 对于集合类型，返回空列表；其他类型返回空对象 */
        /* 注意：这里通过泛型边界判断，无法完全精确，但可覆盖绝大多数场景 */
        Type genericType = getGenericType(); // 获取当前泛型类型（简化实现）
        if (genericType instanceof ParameterizedType) {
            Type rawType = ((ParameterizedType) genericType).getRawType();
            if (List.class.isAssignableFrom((Class<?>) rawType) ||
                    Collection.class.isAssignableFrom((Class<?>) rawType)) {
                return (T) new ArrayList<>(); // 集合类型返回空列表
            } else if (Map.class.isAssignableFrom((Class<?>) rawType)) {
                return (T) new HashMap<>(); // Map类型返回空Map
            }
        }
        // 非集合类型返回空对象（或自定义空DTO）（会被序列化为 {} ）
        return (T) new HashMap<>();
    }

    /*------------------ 链式增强方法 ------------------*/

    /**
     * 链式设置结果码
     *
     * @param code 结果码
     * @return 当前实例（支持链式调用）
     */
    public Result<T> code(int code) {
        this.code = code;
        return this;
    }

    /**
     * 链式设置结果消息
     *
     * @param message 消息内容
     * @return 当前实例（支持链式调用）
     */
    public Result<T> msg(String message) {
        this.msg = message;
        return this;
    }

    /**
     * 链式设置响应数据
     *
     * @param data 数据对象
     * @return 当前实例（支持链式调用）
     */
    public Result<T> data(T data) {
        this.data = (data == null) ? getDefaultEmptyData() : data;
        return this;
    }

    /*------------------ 枚举兼容方法 ------------------*/

    /**
     * 通过状态码枚举构造响应（无数据）
     *
     * @param statusCode 状态码枚举（如 {@link ResultCode}）
     * @return 响应实例
     */
    public static <T> Result<T> of(StatusCode statusCode) {
        return of(statusCode.getCode(), statusCode.getMessage(),  getDefaultEmptyData());
    }

    /**
     * 通过状态码枚举构造响应（携带数据）
     *
     * @param statusCode 状态码枚举
     * @param data       响应数据
     * @return 响应实例
     */
    public static <T> Result<T> of(StatusCode statusCode, T data) {
        T resultData = (data == null) ? getDefaultEmptyData() : data;
        return of(statusCode.getCode(), statusCode.getMessage(), resultData);
    }

    /*------------------ 完全自定义的 of 方法重载 ------------------*/

    /**
     * 完全自定义响应内容（允许覆盖 code/message/data）
     *
     * @param code    结果码
     * @param message 消息内容
     * @param data    响应数据
     * @return 响应实例
     */
    public static <T> Result<T> of(int code, String message, T data) {
        T resultData = (data == null) ? getDefaultEmptyData() : data;
        return new Result<>(code, message, resultData);
    }

    /*------------------ 保留原有的具体枚举方法（可选） ------------------*/

    /**
     * 兼容旧版 {@link ResultCode} 枚举的直接调用
     *
     * @param resultCode 错误码枚举
     * @return 响应实例
     */
    public static <T> Result<T> of(ResultCode resultCode) {
        return of(resultCode.getCode(), resultCode.getMessage(), getDefaultEmptyData());
    }

    /*------------------ 简化的泛型类型获取（可选，非必须） ------------------*/
    // 注意：实际项目中可通过 TypeToken 或反射工具获取更精确的泛型类型
    private static Type getGenericType() {
        return Result.class.getGenericSuperclass();
    }
}